#include "canvas.h"

#include "scene.h"
#include "interpreter.h"

////////////////
//   Canvas   //
////////////////

Canvas::Canvas(){

}

Canvas::~Canvas(){

}

Scene* Canvas::getScene(){
    return this->scene;
}

bool Canvas::onApplication(Cursor &c){
    Viewport viewport = this->scene->getViewport();
    if (c.getX() >= viewport.left and c.getX() <= viewport.left + viewport.width 
    and c.getY() >= viewport.top and c.getY() <= viewport.top + viewport.height)
        return true;
    else
        return false;
}

void Canvas::setViewport(int _left, int _top, int _width, int _height){
    this->scene->setViewport(_left, _top, _width, _height);
}

void Canvas::setWindow(float _left, float _right, float _bottom, float _top){
    this->scene->setWindow(_left, _right, _bottom, _top);
}

///////////////////
//   QGLCanvas   //
///////////////////

QGLCanvas::QGLCanvas(){
    setFocusPolicy(Qt::WheelFocus);
    this->interval = 50;
    this->idTimer = this->startTimer(this->interval);            
}
QGLCanvas::~QGLCanvas(){}

void QGLCanvas::setInterval(int interval){
    this->interval = interval;
    killTimer(this->idTimer);
    this->idTimer = startTimer(this->interval); 
}


void QGLCanvas::keyPressEvent(QKeyEvent *event){
    event->accept();
    int key = QKey::key(event->key());
    onPressKey(key);            
}

void QGLCanvas::keyReleaseEvent(QKeyEvent *event){
    event->accept();
    int key = QKey::key(event->key());
    onReleaseKey(key);  
}  

void QGLCanvas::paintGL(){
    this->paint();
}

void QGLCanvas::initializeGL(){
    this->initialize();
}

void QGLCanvas::resizeGL(int width, int height){
    this->resizeCanvas(width, height);
}

void QGLCanvas::timerEvent(QTimerEvent *event){
    glDraw();
}

void QGLCanvas::saveImage(){
    QString filename = QFileDialog::getSaveFileName(this, "Save Image", ".", "File types: png");
    QImage im = grabFrameBuffer();
    im.save(filename);
}


//////////////////////
//   TabletCanvas   //
//////////////////////

TabletCanvas::TabletCanvas(){
    traceId = 1;
    near=true;
}

TabletCanvas::~TabletCanvas(){

}


void TabletCanvas::tabletEvent(QTabletEvent *event){
    Cursor c = Cursor( traceId, PEN, clock(), 
                       float(event->x()), float(event->y()),
                       event->globalX(), event->globalY(),
                       float(event->pressure()), event->xTilt(), event->yTilt(), 0.0f);
   inputListener(c);
}


void TabletCanvas::inputListener(Cursor &cursor){
    if ( onApplication(cursor) ){
        if (cursor.getPressure()==0){
            if (near){
                this->onNearCursor(cursor);
            }
            else{
                this->onReleaseCursor(cursor);
                near = true;
                traceId++;
            }
        }
        else{
            if (near){
                near = false;
                this->onPressCursor(cursor);
            }
            else{
                this->onMoveCursor(cursor);
            }
        } 
    }
    else{
        this->offCursor(cursor);
    }
}

////////////////////
//   WimpCanvas   //
////////////////////

WimpCanvas::WimpCanvas(){
    traceId = 0;
}

WimpCanvas::~WimpCanvas(){

}

void WimpCanvas::mousePressEvent(QMouseEvent *event){
    traceId++;
    Cursor c = Cursor( traceId, MOUSE, clock(), 
                       float(event->x()), float(event->y()),
                       event->globalX(), event->globalY(), 1.0f, 0.0f, 0.0f, 0.0f);
   onPressCursor(c);
}

void WimpCanvas::mouseMoveEvent(QMouseEvent *event){
    Cursor c = Cursor( traceId, MOUSE, clock(), 
                       float(event->x()), float(event->y()),
                       event->globalX(), event->globalY(), 1.0f, 0.0f, 0.0f, 0.0f);

    onMoveCursor(c);
}    


void WimpCanvas::mouseReleaseEvent(QMouseEvent *event){
    Cursor c = Cursor( traceId, MOUSE, clock(), 
                       float(event->x()), float(event->y()),
                       event->globalX(), event->globalY(), 1.0f, 0.0f, 0.0f, 0.0f);

    onReleaseCursor(c);
}    

////////////////////
//   TuioCanvas   //
////////////////////

TuioCanvas::TuioCanvas(){
    tuioClient = new TuioClient(3333);
    tuioClient->addTuioListener(this);
    tuioClient->connect();
}

TuioCanvas::~TuioCanvas(){

}


void TuioCanvas::addTuioObject(TuioObject *tobj){
    Viewport &viewport = this->scene->getViewport();
    Cursor c = Cursor( tobj->getSymbolID(), FIDUCIAL, clock(), 
                       float(tobj->getScreenX(viewport.width)),
                       float(tobj->getScreenY(viewport.height)),
                       0.0f, 0.0f, 1.0f, 0.0f, 0.0f, tobj->getAngle());
    onPressCursor(c);
}

void TuioCanvas::updateTuioObject(TuioObject *tobj){
    Viewport &viewport = this->scene->getViewport();
    Cursor c = Cursor( tobj->getSymbolID(), FIDUCIAL, clock(), 
                       float(tobj->getScreenX(viewport.width)),
                       float(tobj->getScreenY(viewport.height)),
                       0.0f, 0.0f, 1.0f, 0.0f, 0.0f, tobj->getAngle());
    onMoveCursor(c);
}

void TuioCanvas::removeTuioObject(TuioObject *tobj){
    Viewport &viewport = this->scene->getViewport();
    Cursor c = Cursor( tobj->getSymbolID(), FIDUCIAL, clock(), 
                       float(tobj->getScreenX(viewport.width)),
                       float(tobj->getScreenY(viewport.height)),
                       0.0f, 0.0f, 1.0f, 0.0f, 0.0f, tobj->getAngle());
    onReleaseCursor(c);
}

void TuioCanvas::addTuioCursor(TuioCursor *tcur){
    traceId++;
    Viewport &viewport = this->scene->getViewport();
    Cursor c = Cursor( tcur->getSessionID(), FINGER, clock(), 
                       float(tcur->getScreenX(viewport.width)),
                       float(tcur->getScreenY(viewport.height)),
                       0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
    onPressCursor(c);
}


void TuioCanvas::updateTuioCursor(TuioCursor *tcur){
    Viewport &viewport = this->scene->getViewport();
    Cursor c = Cursor( tcur->getSessionID(), FINGER, clock(), 
                       float(tcur->getScreenX(viewport.width)),
                       float(tcur->getScreenY(viewport.height)),
                       0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
    onMoveCursor(c);
}


void TuioCanvas::removeTuioCursor(TuioCursor *tcur){
    Viewport &viewport = this->scene->getViewport();
    Cursor c = Cursor( tcur->getSessionID(), FINGER, clock(), 
                       float(tcur->getScreenX(viewport.width)),
                       float(tcur->getScreenY(viewport.height)),
                       0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
    onReleaseCursor(c);
}
